package com.cryptoneedle.center.doris.service.dwd;

import cn.hutool.v7.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.cryptoneedle.center.common.constants.CommonConstant;
import com.cryptoneedle.center.common.entity.doris.DorisColumn;
import com.cryptoneedle.center.common.entity.doris.DorisTable;
import com.cryptoneedle.center.common.entity.dwd.DwdColumn;
import com.cryptoneedle.center.common.entity.dwd.DwdTable;
import com.cryptoneedle.center.common.repository.dwd.DwdColumnRepository;
import com.cryptoneedle.center.common.repository.dwd.DwdTableRepository;
import com.cryptoneedle.center.doris.service.doris.DorisColumnService;
import com.cryptoneedle.center.doris.service.doris.DorisTableService;
import com.cryptoneedle.center.source.helper.ConfigPropertyHelper;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * <p>description:  </p>
 *
 * @author CryptoNeedle
 * @date 2025-09-26
 */
@Service
@DS("pg")
@Slf4j
public class DwdSyncService {

    @Resource
    private DorisTableService dorisTableService;

    @Resource
    private DwdTableRepository dwdTableRepository;

    @Resource
    private DorisColumnService dorisColumnService;

    @Resource
    private DwdColumnRepository dwdColumnRepository;

    public void syncDwd() {
        syncTable();
        syncOdsColumn();
    }

    public void syncTable() {
        // 查询所有
        List<DwdTable> originList = dwdTableRepository.list();
        Map<String, DwdTable> originMap = Maps.uniqueIndex(originList, DwdTable::getKeyString);

        // 待同步数据
        List<DorisTable> rearDealList = dorisTableService.listByDatabase(CommonConstant.DORIS_CATALOG, ConfigPropertyHelper.dwd());
        Map<String, DorisTable> realDealMap = Maps.uniqueIndex(rearDealList, DorisTable::getKeyString);

        List<DwdTable> dealList = rearDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, DwdTable.class))
                .toList();
        Map<String, DwdTable> dealMap = Maps.uniqueIndex(dealList, DwdTable::getKeyString);

        // 新增数据
        List<DwdTable> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.getKeyString())).toList();

        // 移除数据
        List<DwdTable> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.getKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<DwdTable> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.getKeyString()))
                .peek(origin -> {
                    DorisTable realDeal = realDealMap.get(origin.getKeyString());
                    BeanUtil.copyProperties(realDeal, origin);
                })
                .toList();

        dwdTableRepository.saveAll(addList);
        dwdTableRepository.saveAll(saveList);
        dwdTableRepository.deleteAll(removeList);
    }

    public void syncOdsColumn(String catalogName, String databaseName, String tableName) {
        // 查询所有
        List<DwdColumn> originList = dwdColumnRepository.listByTable(catalogName, databaseName, tableName);
        Map<String, DwdColumn> originMap = Maps.uniqueIndex(originList, DwdColumn::getKeyString);

        // 待同步数据
        List<DorisColumn> realDealList = dorisColumnService.listByTable(catalogName, databaseName, tableName);
        Map<String, DorisColumn> realDealMap = Maps.uniqueIndex(realDealList, DorisColumn::getKeyString);

        List<DwdColumn> dealList = realDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, DwdColumn.class))
                .toList();
        Map<String, DwdColumn> dealMap = Maps.uniqueIndex(dealList, DwdColumn::getKeyString);

        // 新增数据
        List<DwdColumn> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.getKeyString())).toList();

        // 移除数据
        List<DwdColumn> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.getKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<DwdColumn> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.getKeyString()))
                .peek(origin -> {
                    DorisColumn realDeal = realDealMap.get(origin.getKeyString());
                    BeanUtil.copyProperties(realDeal, origin);
                })
                .toList();

        dwdColumnRepository.saveAll(addList);
        dwdColumnRepository.saveAll(saveList);
        dwdColumnRepository.deleteAll(removeList);
    }

    public void syncOdsColumn() {
        // 查询所有
        List<DwdColumn> originList = dwdColumnRepository.list();
        Map<String, DwdColumn> originMap = Maps.uniqueIndex(originList, DwdColumn::getKeyString);

        // 待同步数据
        List<DorisColumn> realDealList = dorisColumnService.listByDatabase(CommonConstant.DORIS_CATALOG, ConfigPropertyHelper.dwd());
        Map<String, DorisColumn> realDealMap = Maps.uniqueIndex(realDealList, DorisColumn::getKeyString);

        List<DwdColumn> dealList = realDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, DwdColumn.class))
                .toList();
        Map<String, DwdColumn> dealMap = Maps.uniqueIndex(dealList, DwdColumn::getKeyString);

        // 新增数据
        List<DwdColumn> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.getKeyString())).toList();

        // 移除数据
        List<DwdColumn> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.getKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<DwdColumn> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.getKeyString()))
                .peek(origin -> {
                    DorisColumn realDeal = realDealMap.get(origin.getKeyString());
                    BeanUtil.copyProperties(realDeal, origin);
                })
                .toList();

        dwdColumnRepository.saveAll(addList);
        dwdColumnRepository.saveAll(saveList);
        dwdColumnRepository.deleteAll(removeList);
    }
}